package com.meituan.verintreport.task;

import com.meituan.verintreport.db.dao.ReportGoodRecordDao;
import com.meituan.verintreport.db.dto.EvalGoodRecordDto;
import com.meituan.verintreport.db.verint.VerintEvalDataDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 优秀录音
 */
@Slf4j
@Component
//@ConfigurationProperties(prefix = "report.good-record")
public class ReportTasks extends BaseTableTask {
    @Resource
    private ReportGoodRecordDao reportGoodRecordDao;

    @Resource
    private VerintEvalDataDao verintEvalDataDao;

    //@Value("${report.timezone}")
    private String reportTimeZone;

   // @Value("${report.good-record.execute.maxMinutesPerTime}")
    private int maxMinutesPerTime = 15;

    //@Value("${report.good-record.compensate.enable}")
    private boolean isCompensate;
   // @Value("${report.good-record.compensate.start}")
    private String compensateStart;
   // @Value("${report.good-record.compensate.end}")
    private String compensateEnd;

    private static String prevEndTimeStr = null;

    private void doCompensate() {

        log.info("doCompensate startTime = {} endTime = {}", compensateStart, compensateEnd);
        int pageIndex = 0;
        int pageSize = 1000;
        boolean isFirst = false;

        String lastSyncTime = reportGoodRecordDao.getLastSyncTime();
        log.info("last sync time: {}", lastSyncTime);

        boolean shouldContinue = false;
        do {
            shouldContinue = false;

            if (lastSyncTime == null) {
                isFirst = true;
            }
//            else {
//                if (startTimeStr.compareTo(lastSyncTime) > 0) {
//                    startTimeStr = lastSyncTime;
//                }
//            }
            boolean success = true;
            do {
                success = true;
                try {
                    List<EvalGoodRecordDto> records = verintEvalDataDao.getGoodRecordsDatePeriodPaged(compensateStart, compensateEnd, pageIndex, pageSize);
                    log.info("got {} records", records.size());
                    if (records.size() == 1000) {
                        shouldContinue = true;
                    }

                    for (EvalGoodRecordDto record : records) {
                        try {
                            reportGoodRecordDao.addGoodRecord(record);
                        } catch (Exception ex) {
                            log.error("Add Good Record to db exception.", ex);
                        }
                    }

                } catch (Exception ex) {
                    success = false;
                }
            } while (!success);
        }
        while (shouldContinue);

        log.info("doCompensate end");
    }

    //@Scheduled(cron = "${report.good-record.execute.cron}")
    public void execute() {

        if (isCompensate) {
            isCompensate = false;
            doCompensate();
        }

        if (!isEnable()) return;

        long startTime = System.currentTimeMillis();
        Calendar beforeTime = Calendar.getInstance();
        TimeZone timezone = TimeZone.getTimeZone(reportTimeZone);
        beforeTime.setTimeZone(timezone);
        beforeTime.add(Calendar.HOUR_OF_DAY, -2);// 1小时// 之前的时间
        beforeTime.set(Calendar.MINUTE, 0);
        beforeTime.set(Calendar.SECOND, 0);
        beforeTime.set(Calendar.MILLISECOND, 0);
        Date beginTime = beforeTime.getTime();

        Calendar beforeTime1 = Calendar.getInstance();
        beforeTime1.setTimeZone(timezone);
        beforeTime1.add(Calendar.HOUR_OF_DAY, -1);
        beforeTime1.set(Calendar.MINUTE, 0);
        beforeTime1.set(Calendar.SECOND, 0);
        beforeTime1.set(Calendar.MILLISECOND, 0);
        Date endDateTime = beforeTime1.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(timezone);

        String startTimeStr = sdf.format(beginTime) + ".000";
        String endTimeStr = sdf.format(endDateTime) + ".000";

        log.info("timezone = {} startTime = {} endTime = {}", timezone.getDisplayName(), startTimeStr, endTimeStr);

        if (prevEndTimeStr == null) {
        } else {
            if (!prevEndTimeStr.equals(startTimeStr) && endTimeStr.compareTo(prevEndTimeStr) > 0) {
                startTimeStr = prevEndTimeStr;

                log.info("May be missed fire : {}", startTimeStr);
                log.info("Run with compensate time range: startTime = {} endTime = {}", startTimeStr, endTimeStr);
            } else {
                if (prevEndTimeStr.equals(endTimeStr)) {
                    log.warn("Time range could be fired (ignore this): startTime = {} endTime = {}", startTimeStr, endTimeStr);
                    return;
                }
            }
        }

        prevEndTimeStr = endTimeStr;

        int pageIndex = 0;
        int pageSize = 1000;
        boolean isFirst = false;

        String lastSyncTime = reportGoodRecordDao.getLastSyncTime();
        log.info("last sync time: {}", lastSyncTime);

        boolean shouldContinue = false;
        do {
            shouldContinue = false;

            if (lastSyncTime == null) {
                isFirst = true;
            }

            boolean success = true;
            do {
                success = true;
                try {
                    List<EvalGoodRecordDto> records = verintEvalDataDao.getGoodRecordsDatePeriodPaged(isFirst ? null : startTimeStr, endTimeStr, pageIndex, pageSize);
                    log.info("got {} records", records.size());
                    if (records.size() == 1000) {
                        shouldContinue = true;
                    }

                    for (EvalGoodRecordDto record : records) {
                        try {
                            reportGoodRecordDao.addGoodRecord(record);
                        } catch (Exception ex) {
                            log.error("Add Good Record to db exception.", ex);
                        }
                    }

                } catch (Exception ex) {
                    success = false;
                }
            } while (!success);
//            long endTime = System.currentTimeMillis();
//            if (endTime - startTime > maxMinutesPerTime * 60 * 1000) {
//                shouldContinue = false;
//            }
        }
        while (shouldContinue);
    }
}
